package 动态规划;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 300. 最长递增子序列
 * 给你一个整数数组 nums ，找到其中最长严格递增子序列的长度。
 *
 * 子序列 是由数组派生而来的序列，删除（或不删除）数组中的元素而不改变其余元素的顺序。例如，[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的
 * 思路： 使用动态规划
 * 1:状态转移数组的定义，使用dp[i] 表示以nums[i]结尾的最长递增子序列的长度
 * 2：状态转移方程的推导定义：
 *      对于每一个元素nums[i],遍历前面的所有元素nums[j]，确保（j < i）, 如果nums[j] < mums[i],则 dp[i] 的值为 dp[j] + 1，取所有可能的最大值。
 *      所以状态转移方程为dp[i] = max(dp[i], dp[j] + 1)
 *  3：初始化： 该dp数组的默认值都为1。
 *  4: 这样，就可获取的当前i位上最长的连续子序列长度，遍历dp，取最大值即可。
 */
public class L_300 {
    public int lengthOfLIS(int[] nums) {
        if(nums.length == 0){
            return -1;
        }
        int[] dp = new int[nums.length+1];
        // 填充dp数组
        Arrays.fill(dp, 1);

        for (int i = 1; i < nums.length; i++) {
            // 当前i上的前j位都需要对比
            for (int j = 0; j < i; j++) {
                // 如果连续，则更新dp[i]
                if (nums[i] > nums[j]){
                    dp[i] = Math.max(dp[i],dp[j] + 1);
                }
            }
        }

        // 遍历dp数组，取最大值即可。
        int res = 0;
        for (int i = 0; i < dp.length; i++) {
            res = Math.max(res,dp[i]);
        }
        return res;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入数组长度:");
        int numsLen = scanner.nextInt();
        int[] nums = new int[numsLen];
        System.out.println("请逐个输入数组元素：");
        for (int i = 0; i < numsLen; i++) {
            nums[i] = scanner.nextInt();
        }

        L_300 l300 = new L_300();
        int result = l300.lengthOfLIS(nums);
        System.out.println("最长递增子序列长度：" + result);
    }
}
